package service

import (
	"errors"
	"fmt"
	"ssadmin/common/constant"
	"ssadmin/internal/admin/models"
	"ssadmin/internal/admin/models/command"
	"ssadmin/internal/admin/models/query"
	"strings"
	"time"

	"gitee.com/sansaniot/ssiot-core/httpmvc/service"
	uuid "github.com/satori/go.uuid"
	"gorm.io/gorm"

	cDto "ssadmin/common/query"
	"ssadmin/common/utils"
)

type Register struct {
	service.Service
	CurrUser map[string]interface{}
}

// GetPage 获取Register列表
func (e *Register) GetPage(c *query.RegisterQuery, list *[]models.Register, count *int64) error {
	data := models.Register{}
	err := data.FindPage(e.Orm, &list, count,
		cDto.MakeCondition(c.GetNeedSearch()),
		cDto.OrderDest("modify_time", true),
		cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
	)
	for i, info := range *list {
		mtime := info.ModifyTimeDts.Format(utils.TIME_FMT_FULL)
		if strings.Contains(mtime, utils.TIME_NIL) {
			mtime = ""
		}

		ctime := info.CreateTimeDts.Format(utils.TIME_FMT_FULL)
		if strings.Contains(ctime, utils.TIME_NIL) {
			ctime = ""
		}
		(*list)[i].ModifyTime = mtime
		(*list)[i].CreateTime = ctime
	}
	return err
}

// GetProfile 获取Register对象
func (e *Register) GetProfile(c *command.RegisterGetReq, model *models.Register) error {
	data := models.Register{}

	id := query.RegisterQuery{Id: c.Id, UserName: c.UserName}
	where := cDto.MakeCondition(id)
	if err := data.FindOne(e.Orm, &model, where); err != nil {
		return err
	}

	model.CreateTime = model.CreateTimeDts.Format(utils.TIME_FMT_FULL)
	model.ModifyTime = model.ModifyTimeDts.Format(utils.TIME_FMT_FULL)
	if eq := strings.Contains(model.ModifyTime, utils.TIME_NIL); eq {
		model.ModifyTime = ""
	}
	return nil
}

//创建角色
func (e *Register) newRoleAndMenu(tx *gorm.DB, c *command.RegisterInsertReq) (doSaveRoleList []models.Role, err error) {
	roleModel := models.Role{}
	roleMenuModel := models.RoleMenu{}
	where := "id in (?)"
	whereR := "role_id in (?)"

	//查询角色列表
	roleList := make([]models.Role, 0)
	defaultRole := []string{
		constant.DefaultRole,
	}
	if err = roleModel.FindListByConds(tx, &roleList, where, defaultRole); err != nil {
		return
	}
	if len(roleList) == 0 {
		err = errors.New(fmt.Sprintf("无法给 %s 分配角色，请检查默认角色参数 %s", c.UserName, strings.Join(defaultRole, ",")))
		return
	}

	//查询角色菜单列表
	roleMenuList := make([]models.RoleMenu, 1)
	if err = roleMenuModel.FindListByConds(tx, &roleMenuList, whereR, defaultRole); err != nil {
		return
	}

	if len(roleMenuList) == 0 {
		err = errors.New(fmt.Sprintf("无法给 %s 分配菜单权限", c.UserName))
		return
	}

	doSaveRoleList = append(roleList)

	return
}

//添加新用户
func (e *Register) newBizUser(tx *gorm.DB, c *command.RegisterInsertReq, deptId string, doSaveRoleList []models.Role) error {
	userInfo := models.User{
		UserId:        uuid.NewV4().String(),
		Username:      c.UserName,
		Password:      c.Password,
		Mobile:        c.Mobile,
		CreateTimeDts: time.Now(),
		ModifyTime:    time.Now(),
		Alias:         c.Alias,
		Company:       c.Company,
		Email:         c.Email,
		IsAgency:      constant.AgencyUser,
		CreatorId:     utils.If(len(c.CreatorId) == 0, e.CurrUser[constant.CacheKeyUserId], c.CreatorId).(string),
		Creator:       utils.If(len(c.Creator) == 0, e.CurrUser[constant.CacheKeyUserName], c.Creator).(string),
		Status:        "1",
	}

	userInfo.Agency = userInfo.UserId
	ur := models.UserRole{}
	userRoles := make([]models.UserRole, 0)

	for _, v := range doSaveRoleList {
		userRoles = append(userRoles, models.UserRole{
			RoleId: v.RoleId,
			UserId: userInfo.UserId,
		})
	}

	//添加用户
	if err := userInfo.Add(tx, &userInfo); err != nil {
		return err
	}

	//用户分组
	cd := models.UserDept{
		UserId: userInfo.UserId,
		DeptId: deptId,
	}

	if err := cd.Add(tx, &cd); err != nil {
		return err
	}

	// 添加公共分组
	publicDepts := strings.Split(constant.PublicDept, ",")
	for _, pid := range publicDepts {
		ud := models.UserDept{
			UserId: userInfo.UserId,
			DeptId: pid,
		}

		if err := cd.Add(tx, &ud); err != nil {
			return err
		}
	}

	// 用户角色
	if len(userRoles) > 0 {
		if err := ur.Add(tx, &userRoles); err != nil {
			return err
		}
	}

	//管理员分组
	cud := models.UserDept{
		UserId: utils.If(len(c.CreatorId) == 0, e.CurrUser[constant.CacheKeyUserId], c.CreatorId).(string),
		DeptId: deptId,
	}
	if err := cud.Add(tx, &cud); err != nil {
		return err
	}
	return nil
}

//生成用户机构
func (e *Register) newDept(tx *gorm.DB, d *command.RegisterInsertReq) (deptId string, err error) {
	did := uuid.NewV4().String()
	deptModel := models.Dept{
		DeptId:        did,
		ParentId:      "root",
		DeptName:      d.Company,
		CreateTimeDts: time.Now(),
		CreatorId:     utils.If(len(d.CreatorId) == 0, e.CurrUser[constant.CacheKeyUserId], d.CreatorId).(string),
	}
	if err = deptModel.Add(tx, &deptModel); err != nil {
		return did, err
	}
	return did, nil
}

//更新注冊用户信息
func (e *Register) updateRegisterUser(tx *gorm.DB, c *command.RegisterInsertReq) error {
	data := models.Register{}
	where := cDto.MakeCondition(query.RegisterQuery{
		UserName: c.UserName,
		Email:    c.Email,
		Mobile:   c.Mobile,
	})
	if err := data.FindOne(tx, &data, where); err != nil {
		return err
	}
	data.Status = constant.RegistStatusAudited
	data.ModifyTimeDts = time.Now()
	if err := data.Mod(tx, &data, where); err != nil {
		return err
	}
	return nil
}

// GetByRegistername 获取Register对象
func (e *Register) GetByRegistername(username string, model *models.Register) {
	if len(username) == 0 {
		return
	}
	data := models.Register{}
	where := cDto.MakeCondition(query.RegisterQuery{UserName: username})
	if err := data.FindOne(e.Orm, &model, where); err != nil {
		return
	}

}

// Insert 创建Register对象
func (e *Register) Insert(c *command.RegisterInsertReq) error {
	passwdForgetReq := command.PasswordForgetResetReq{
		Code:   c.Code,
		Mobile: c.Mobile,
	}

	//校验验证码
	vs := VerifyCode{}
	if err := vs.ValidCode(&passwdForgetReq); err != nil {
		return err
	}

	err := c.Generate()
	if err != nil {
		return err
	}

	//校验用户是否注册过
	var count int64
	userModel := models.User{}
	userModel.FindCountByConds(e.Orm, &count, "username = ?", c.UserName)
	if count > 0 {
		return errors.New(fmt.Sprintf("用户名已被使用", c.UserName))
	}

	userModel.FindCountByConds(e.Orm, &count, "mobile = ?", c.Mobile)
	if count > 0 {
		return errors.New(fmt.Sprintf("手机号已被使用", c.Mobile))
	}

	// 自动通过审核、创建注册用户
	if err := e.Orm.Transaction(func(tx *gorm.DB) error {
		// 创建以注册公司名为分组名的分组
		c.CreatorId = constant.AdminUser
		c.Creator = "admin"
		deptId, err := e.newDept(tx, c)

		if err != nil {
			return err
		}

		// 角色
		doSaveRoleList, err := e.newRoleAndMenu(tx, c)
		if err != nil {
			return err
		}

		// 创建用户，设置密码、创建用户
		if err := e.newBizUser(tx, c, deptId, doSaveRoleList); err != nil {
			return err
		}

		return nil
	}); err != nil {
		return err
	}

	return nil
}

// Update 修改Register对象
func (e *Register) Update(c *command.RegisterUpdateReq) error {
	if len(c.Id) == 0 {
		return errors.New("用户ID不能为空")
	}
	data := models.Register{}

	id := query.RegisterQuery{Id: c.Id}
	where := cDto.MakeCondition(id)

	if err := data.FindOne(e.Orm, &data, where); err != nil {
		return err
	}

	c.Generate(&data)
	if err := data.Mod(e.Orm, &data, where); err != nil {
		return err
	}
	return nil
}
